<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2018/6/13
 * Time: 23:01
 */

namespace app\common\model;

use app\common\cachemodel\ArticleCommentReply;
use app\common\cachemodel\ForbidenRecord;
use app\common\cachemodel\ZlUserNoComment;
use app\common\cachemodel\ZlUserVip;
use app\common\lib\exception\ApiException;
use think\Cache;
use think\Exception;

/**
 * 文章评论相关模型
 * Class ArticleComment
 * @package app\common\model
 */
class ArticleComment extends Base
{
    protected $table = 'wechatadmin.system_article_comment';

    protected $insert = ['create_time'];

    const ARTICLE_COMMENT_ID = 'article_comment_id_';//相关文章的所有评论id
    const ARTICLE_COMMENT = 'article_comment_';//评论详情缓存键名
    const CACHE_TIME = 86400 * 3;

    public function setCreateTimeAttr($value)
    {
        return time();
    }

    /**
     * 关联文章
     * @return \think\model\relation\belongsTo
     */
    public function article()
    {
        return $this->belongsTo('Article', 'id', 'aid');
    }

    /**
     * 关联评论的回复
     * @return \think\model\relation\HasMany
     */
    public function reply()
    {
        return $this->hasMany('ArticleCommentReply', 'comment_id', 'id');
    }

    /**
     * 获取当前文章的所有评论及三条回复信息
     * @param array $map
     * @return array
     * @throws \Exception
     */
    public function getComments($map = [])
    {
        return (new \app\common\cachemodel\ArticleComment())->getPageCommentList($map['uid'], 1, (int)$map['aid'], 1, (int)$map['page']);


        $aid = $map['aid'];

        $page = $map['page'];

        $ucid = $map['uc_id'];
        $uid = $map['uid'];

        $article_comment_id_list = false;

        if ($this->cache_on >= 1)
        {
            // 获取当前文章评论id数组  --根据文章id
            $article_comment_id_list = Cache::get(self::ARTICLE_COMMENT_ID . $aid);
        }

        // 获取当前文章的所有评论的id
        if ($article_comment_id_list === false)
        {
            try
            {
                $data = $this->field('id')
                    ->where(['aid' => $aid, 'status' => 0])
                    ->order('id DESC')
                    ->selectOrFail();
                $data = json_decode(json_encode($data, true), true);

                // 将评论id组成字符串
                if (!empty($data)) foreach ($data as $acl) $article_comment_id_list .= $acl['id'] . ',';

                // 缓存评论id,根据文章id
                if ($this->cache_on >= 1)
                    Cache::set(self::ARTICLE_COMMENT_ID . $aid, $article_comment_id_list, self::CACHE_TIME);
            }
            catch (\Exception $e)
            {
                $article_comment_id_list = '';// 文章列表默认为空
            }
        }

        // 将评论id转为数组
        $article_comment_id_list = explode(',', $article_comment_id_list);

        $per_page = 10;// 当前文章评论每页显示数量
        // 去除数组最后一个元素
        array_pop($article_comment_id_list);

        // 统计有多少评论
        $total = count($article_comment_id_list);
        //获取数据分页信息
        $data_list = getPaginatorData($total, $page, $per_page);

        //获取分页后的评论id数组
        $article_comment = array_slice($article_comment_id_list, $data_list['start'], $per_page);

        unset($data_list['start']);
        unset($data_list['end']);

        // 根据当前页评论id获取所需的评论内容
        if (!empty($article_comment))
        {
            $ac_ids = '';
            $temp = [];

            // 从缓存评论内容,根据评论id
            foreach ($article_comment as $ac_id)
            {
                if ($this->cache_on >= 1)
                {
                    // 根据评论id 获取评论内容
                    $temp[$ac_id] = Cache::get(self::ARTICLE_COMMENT . $ac_id);
                } else
                {
                    $temp[$ac_id] = false;
                }

                // 评论内容未缓存，等待从数据库中获取
                if ($temp[$ac_id] === false)
                {
                    $ac_ids .= ',' . $ac_id;
                }
            }

            // 从数据库获取评论内容
            if ($ac_ids != '' || strlen($ac_ids) > 0)
            {
                // 去掉开头的,
                $ac_ids = substr($ac_ids, 1);

                try
                {
                    $comments = $this->alias('ac')
                        ->field('ac.id,ac.aid,u.id uid,ac.content,ac.status,ac.create_time,ac.goods,ac.reply,u.nickname,u.avatar,ac.ucid')
                        ->join('wechat_backup_07_18_14_43_00.app_user u', 'u.uc_id=ac.ucid', 'INNER')
                        ->where('ac.id in(' . $ac_ids . ')')
                        ->where(['ac.status' => 0, 'u.forbidden' => 0])
                        ->order('ac.is_top DESC, ac.id DESC')
                        ->selectOrFail();
                    $comments = json_decode(json_encode($comments, true), true);
                }
                catch (\Exception $e)
                {
                    $comments = [];
                }

                if (!empty($comments))
                {
                    foreach ($comments as $c)
                    {
                        $c['content'] = htmlspecialchars_decode($c['content']);
                        // 将评论内容缓存
                        if ($this->cache_on >= 1)
                            Cache::set(self::ARTICLE_COMMENT . $c['id'], $c, self::CACHE_TIME);
                        // 将数据库查出来的内容 写入到数组中为空的部分
                        $temp[$c['id']] = $c;
                    }
                }
            }

            $commentGoodsModel = new ArticleCommentGood();
            if ($uid)
            {
                $goods = $commentGoodsModel->getAllCommentGood(['ucid' => $ucid, 'uid' => $uid]);
            } else
            {
                $goods = [];
            }

            // 重组评论数据
            foreach ($temp as $k => $d)
            {
                if ($d)
                {
                    if ($uid)
                    {
                        // 判断当前评论是否为自己的评论   前台显示删除按钮
                        if ($d['ucid'] == $ucid) $d['is_owner'] = true;
                        // 默认不是自己的
                        else $d['is_owner'] = false;
                        unset($d['ucid']);

                        // 默认点赞状态关闭
                        $d['good_status'] = false;
                        // 获取评论点赞状态  当前用户是否已赞
//                    $commentGoodModel = new ArticleCommentGood();
//                    $good = $commentGoodModel->getCommentGood([
//                        'aid' => $aid,
//                        'ucid' => $ucid,
//                        'ac_id' => $d['id'],
//                        'uid' => $map['uid'],
//                    ]);

                        // 更改点赞状态为开启
//                    if ($good) $d['good_status'] = true;

                        foreach ($goods as $kk => $vv)
                        {
                            if ($vv['aid'] == $aid && $vv['ucid'] == $ucid && $vv['comment_id'] == $d['id'])
                            {
                                $d['good_status'] = true;
                            }
                        }
                    } else
                    {
                        unset($d['ucid']);
                        $d['is_owner'] = false;
                        $d['good_status'] = false;
                    }


                    // 默认回复内容为null
                    $reply_list = NULL;
                    // 获取回复内容
                    $commentReplyModel = new ArticleCommentReply();
                    $reply_list = $commentReplyModel->getReplyLists(['ac_id' => $d['id'], 'page' => $page], 1, false);
//                    \think\Log::write(var_export($reply_list['data']),'log',true);
                    if (!empty($reply_list))
                    {
                        // 获取二级回复
                        foreach ($reply_list['data'] as $k2 => $rl)
                        {
                            if (isset($rl['pid']) && !$rl['pid'])
                            {
                                // 上级的昵称
                                $new_nickname = $commentReplyModel->getReplylevelName(['reply_pid' => $rl['pid'], 'reply_id' => $rl['id']]);
                                if ($new_nickname)
                                {
                                    $reply_list['data'][$k2]['nickname2'] = $new_nickname['nickname'];
                                } else
                                {
                                    $reply_list['data'][$k2]['nickname2'] = NULL;
                                }
                            }
                        }
                    }
//                    \think\Log::write(var_export($reply_list['data']),'log',true);
//                     获取用户VIP等级
                    $d['vip'] = (isset($d['uid']) && $d['uid']) ? (new ZlUserVip())->getUserVipLevel($d['uid']) : 0;

                    unset($d['uid']);

                    $d['reply_list'] = $reply_list['data'];
                    $data_list['data'][] = $d;
                }
            }

        }
        return $data_list;
    }

    /**添加评论
     * @param array $userInfo
     * @param array $map
     * @param bool $complainSwitch
     * @return bool|array
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \app\common\lib\exception\ApiException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function add_comment(array $userInfo, $map = [], $complainSwitch = true)
    {
        $data = [
            'aid' => $map['aid'],
            'uid' => (int)$userInfo['id'],
            'content' => $map['content'],
            'type' => 1,    //类型 1=>星文评论，2=>女神动态评论，3=>女神专区评论 必传
            'status' => 0   // 状态 0 正常 -1 删除
        ];
        $res = (new \app\common\cachemodel\ArticleComment())->commentAdd($userInfo, $data, $complainSwitch);

        if (!$res['status'])
        {
            throw new ApiException($res['msg'], 200, config('code.error'));
        }

        return [
            'id' => (int)$res['id'],
            'aid' => $map['aid'],
            'content' => $map['content'],
            'status' => 0,
            'create_time' => request()->time(),
            'goods' => 0,
            'reply' => 0,
            'nickname' => $userInfo['nickname'],
            'avatar' => $userInfo['avatar'],
            'is_owner' => true,
            'cid' => (int)$res['id'],
            'good_status' => false,
        ];

//--------------------------------------------------------------------------------
        $id = $map['aid'];  // 文章id
        $content = $map['content']; // 评论内容
        $uc_id = $map['ucid'];
        $map['create_time'] = time();

        $comment = $this->where(['aid' => $id, 'ucid' => $uc_id, 'content' => $content, 'status' => 0, 'create_time' => $map['create_time']])->find();

        // 非重复评论  新增评论
        if ($comment === NULL)
        {
            try
            {
                $cid = $this->insertGetId($map);
                $this->table('wechatadmin.system_article')->where('id', $id)->setInc('comment');

                // 返回当前评论的信息放在前台显示
                $comment = $this->alias('ac')
                    ->field('ac.id,ac.aid,ac.content,ac.status,ac.create_time,ac.goods,
                    ac.reply,u.nickname,u.avatar')
                    ->join('wechat_backup_07_18_14_43_00.app_user u', 'u.uc_id=ac.ucid', 'INNER')
                    ->where(['aid' => $id, 'ucid' => $uc_id, 'content' => $content])
                    ->find();

                $comment['is_owner'] = true;
                $comment['cid'] = $cid;
                $comment['good_status'] = false;
                $comment['content'] = isset($comment['content']) ? htmlspecialchars_decode($comment['content']) : '';
                if ($this->cache_on >= 1)
                    Cache::rm('article_comment_id_' . $id);

                return $comment;
            }
            catch (\Exception $e)
            {
                return false;
            }
        } else
        {
            return false;
        }
    }


    /**
     * 软删除用户当前评论
     * @param array $userInfo
     * @param int $cid 文章ID
     * @return bool
     */
    public function deleteComment(array $userInfo, int $cid): bool
    {
        $aid = $this->alias('ac')
            ->where('ac.id', $cid)
            ->value('aid');

        try
        {
            $this->save(['status' => -1], ['id' => $cid]);

            Cache::rm('article_comment_id_' . $aid); // 删除对应文章评论id数组
            Cache::rm('article_comment_' . $cid);  // 删除对应评论内容缓存
            Cache::rm('article_comment_good_' . $cid); // 删除对应评论点赞缓存
            Cache::rm('comment_reply_id_' . $cid); // 根据评论id，删除对应回复id数组
            Cache::rm('user:reply:' . $userInfo['uid']); // 删除对应用户回复id数组
            Cache::rm('read_reply_' . $userInfo['uid']);//用户回复缓存
            Cache::rm('comment:reply:' . $cid);// // 删除该用户回复详情
        }
        catch (\Exception $e)
        {
            \think\Log::write('api举报，软删除当前评论异常，后台手动处理' . $e->getMessage(), 'error', true);
            return false;
        }
        return true;
    }

    /**
     * 删除用户所有文章评论和评论回复
     * @param array $userInfo 用户信息
     * @param int $adminUid API管理员【VIP3】用户ID
     * @param int $type 1=>用户封号 2=>用户评论禁言
     * @param string $reason 封号原因
     * @return bool
     * @throws \Exception
     */
    public function deleteCommentAll(array $userInfo, int $adminUid = 0, int $type = 0, string $reason = ''): bool
    {
        try
        {
            if ($type === 1)
            {   // 封号
                (new \app\common\cachemodel\User())->save(['forbidden' => 1], ['id' => $userInfo['uid']]);
                //添加封号记录
                (new ForbidenRecord())->saveData($userInfo['uid'], $adminUid, $reason);
            }

            if ($type === 2)
            {   // 文章评论禁言
                $noCommentData = [
                    'uid' => $userInfo['uid'],
                    'atype' => 1,
                    'aid' => $adminUid,
                    'create_time' => time()
                ];
                (new ZlUserNoComment())->save($noCommentData);
            }
            //软删除该用户的文章评论
            $this->where('ucid', $userInfo['ucid'])->update(['status' => -1]);
            //软删除该用户的评论回复
            (new ArticleCommentReply())->where('ucid', $userInfo['ucid'])->update(['status' => -1]);
        }
        catch (Exception $e)
        {
            \think\Log::write('api举报异常，错误信息：' . $e->getMessage() . '行数：' . $e->getLine(), 'error', true);
            return false;
        }
        //清除缓存
        $this->clearCache($userInfo['ucid'], $userInfo['uid']);

        Cache::rm('user:reply:' . $userInfo['uid']); // 删除对应用户回复id数组
        if ($type !== 0)
        {   // 删除用户缓存
            Cache::rm('userinfo:' . $userInfo['uid']);
        }
        return true;
    }

    /**
     * 清除文章评论缓存
     * @param $ucid
     * @param $uid
     * @throws \Exception
     */
    public function clearCache($ucid, $uid)
    {
        $acids = $this->field('id,aid')->where('ucid', $ucid)->select();
        $acrids = (new ArticleCommentReply())->field('id,comment_id')->where('ucid', $ucid)->select();
        // 删除所有评论缓存
        if (!empty($acids))
        {
            // 用户文章评论表id
            foreach ($acids as $ac)
            {
                Cache::rm('article_comment_' . $ac['id']);  // 删除对应评论内容缓存
                Cache::rm('article_comment_good_' . $ac['id']); // 删除对应评论点赞缓存
                Cache::rm('comment_reply_id_' . $ac['id']); // 根据评论id，删除对应回复id数组
                Cache::rm('article_comment_id_' . $ac['aid']); // 删除对应文章评论id
            }

            Cache::rm('user:reply:' . $uid); // 删除对应用户回复id
            Cache::rm('read_reply_' . $uid);//用户回复缓存
        }
        // 删除所有回复缓存
        if (!empty($acrids))
        {
            foreach ($acrids as $acr)
            {
                Cache::rm('comment:reply:' . $acr['id']);// 删除该用户回复详情
                Cache::rm('comment_reply_id_' . $acr['comment_id']); // 根据评论id，删除对应回复id数组
            }
        }
    }
}
